package com.alibaba.citrus.ots.sales.plan.facade.service.salesplan.publish;

import com.alibaba.citrus.ots.common.exception.ActivityException;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.sales.plan.api.setting.SalesPlanStrategyDetailQueryService;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.DispatchPlanScItemRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QueryPlanScItemExtendRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QueryPlanScItemStatRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanStrategyListRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesOrgRatioDTO;
import com.alibaba.citrus.ots.sales.plan.dto.api.response.SalesPlanStrategyDetailResponse;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesPlanCheckStatusEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesPlanModelEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesPlanStatusEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesStatBizTypeEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.StatPoolTypeEnum;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanOrganizationRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanScItemExtendRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanScItemStatRepository;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanScItemExtendSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanStatScItemSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanStrategyDetailSDO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.BatchDeletePlanScItemExtendRequest;
import com.epoch.app.bcots.service.SalesPlanService;
import com.epoch.app.otsplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.otsplatformenhance.model.dto.GetDownOrganizationListRequest;
import com.epoch.app.otsplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.otsplatformenhance.service.OtsPlatformEnhanceService;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;


@Service
public class ChangeDemo {

    private static final Log log = Log.getLogger(ChangeDemo.class);

    @Resource
    private SalesPlanRepository salesPlanRepository;

    @Resource
    private SalesPlanScItemExtendRepository salesPlanScItemExtendRepository;

    @Resource
    private SalesPlanScItemStatRepository salesPlanScItemStatRepository;

    @Resource
    private SalesPlanStrategyDetailQueryService salesPlanStrategyDetailQueryService;

    @Resource
    private SalesPlanOrganizationRepository organizationRepository;

    @Resource
    private SalesPlanService salesPlanService;

    @Resource
    private OtsPlatformEnhanceService otsPlatformEnhanceService;


    /**
     * 生成部门任务量
     *
     * @param dispatchPlanScItemRequest
     * @return
     */
    private Boolean dispatchPlanScItemForDepartmentNewV2(DispatchPlanScItemRequest dispatchPlanScItemRequest) {

        // 0、基本参数校验
        checkParam(dispatchPlanScItemRequest);
        // 0.5 先删除在新增
        BatchDeletePlanScItemExtendRequest batchDeletePlanScItemExtendRequest = new BatchDeletePlanScItemExtendRequest();
        batchDeletePlanScItemExtendRequest.setPlanId(dispatchPlanScItemRequest.getPlanId());
        batchDeletePlanScItemExtendRequest.setBizType(2);
        batchDeletePlanScItemExtendRequest.setPoolType(2);
        log.info("删除部门回复量extend请求入参{}", JSONObject.toJSONString(batchDeletePlanScItemExtendRequest));
        salesPlanService.batchDeletePlanScItemExtend(batchDeletePlanScItemExtendRequest);


        // 1、根据计划id查询  计划是否是待发布状态
        String planId = dispatchPlanScItemRequest.getPlanId();
        SalesPlanSDO salesPlanSDO = checkPlan(planId);
        // 2、查询分子公司的货品回复量
        QueryPlanScItemExtendRequest queryPlanScItemExtendRequest = new QueryPlanScItemExtendRequest();
        queryPlanScItemExtendRequest.setPlanId(Long.valueOf(planId));
        queryPlanScItemExtendRequest.setBizType(SalesStatBizTypeEnum.BUSINESS_UNIT.getBizType());
        queryPlanScItemExtendRequest.setBizId(salesPlanSDO.getOrgBusinessUnitCode());
        queryPlanScItemExtendRequest.setPoolType(Objects.toString(StatPoolTypeEnum.SC_ITEM.getPoolType()));
        queryPlanScItemExtendRequest.setModel(SalesPlanModelEnum.PLAN_MODEL.getModel());
        log.info("分子公司的货品回复量查询参数{}", JSON.toJSONString(queryPlanScItemExtendRequest));
        List<SalesPlanScItemExtendSDO> salesPlanScItemExtendSDOList = salesPlanScItemExtendRepository.batchQueryPlanScItemExtend(queryPlanScItemExtendRequest);
        log.info("分子公司的货品回复量查询结果{}", JSON.toJSONString(salesPlanScItemExtendSDOList));
        if (CollectionUtils.isEmpty(salesPlanScItemExtendSDOList)) {
            throw new FacadeException("OTS-02-004-01-15-009");
        }

        //----> TODO Start： 这里将部分RPC请求抽取出来，避免多次循环引入的超时问题， 查询分子公司（业务单元）的销售组织占比和获取全局组织->部门 & 计划货品信息
        SalesPlanStrategyDetailResponse salesPlanStrategyDetailResponse = tinglangFunc1(salesPlanSDO);
        Map</* depId */ String, SalesPlanStrategyDetailSDO> salesPlanStrategyDetailSDOMap = salesPlanStrategyDetailResponse
                .getSalesPlanStrategyDetailDepartmentList()
                .stream().collect(Collectors.toMap(SalesPlanStrategyDetailSDO::getReplyTargetId, x -> x));

        List<SalesOrgRatioDTO> salesOrgRatioDTOList = salesPlanStrategyDetailResponse.getSalesOrgRatioDTOList();
        CompanyScItemPlanInfo companyScItemPlanInfo = tinglangFunc2(planId, salesOrgRatioDTOList, salesPlanStrategyDetailResponse);
        //----> TODO End： 全局RPC操作结束

        List<SalesPlanScItemExtendSDO> planScItemExtendSDOAllList = new ArrayList<>();
        // 遍历分子公司的计划货品
        for (SalesPlanScItemExtendSDO salesPlanScItemExtendSDO : salesPlanScItemExtendSDOList) {
            // 业务单元货品计划提报量
            Integer monthCount = salesPlanScItemExtendSDO.getMonthCount();
            // 业务单元货品上旬回复量
            Integer monthFirstReturnCount = salesPlanScItemExtendSDO.getMonthFirstReturnCount();
            // 业务单元货品中旬回复量
            Integer monthMiddleReturnCount = salesPlanScItemExtendSDO.getMonthMiddleReturnCount();
            // 业务单元货品下旬回复量
            Integer monthLastReturnCount = salesPlanScItemExtendSDO.getMonthLastReturnCount();
            // 业务单元货品回复量总和
            Integer monthReturnCount = monthFirstReturnCount + monthMiddleReturnCount + monthLastReturnCount;
            log.info("分子公司遍历的货品{}", JSON.toJSONString(salesPlanScItemExtendSDO));

            // 比较业务单元货品回复量和货品计划提报量的大小
            // 回复量大于提报量，按提报量向下回复（原计划三旬提报量就是回复量，也就是合同量）
            log.info("分子公司遍历的货品的提报量={},回复量={}", monthCount, monthReturnCount);
            if (monthReturnCount >= monthCount) {
                //  公司级别的每个货品
                String scItemId = salesPlanScItemExtendSDO.getScItemId();
                // 查询该公司下  所有部门下的该一个货品
                QueryPlanScItemStatRequest queryPlanScItemStatRequest = new QueryPlanScItemStatRequest();
                queryPlanScItemStatRequest.setPlanId(Long.parseLong(planId));
                queryPlanScItemStatRequest.setScItemId(scItemId);
                queryPlanScItemStatRequest.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
                queryPlanScItemStatRequest.setPoolType(Objects.toString(StatPoolTypeEnum.SC_ITEM.getPoolType()));
                queryPlanScItemStatRequest.setStart(0);
                queryPlanScItemStatRequest.setLimit(1000);
                PageResult<List<SalesPlanStatScItemSDO>> result = salesPlanScItemStatRepository.batchQueryPlanScItemByBizId(queryPlanScItemStatRequest);
                if (null == result || CollectionUtils.isEmpty(result.getContent())) {
                    continue;
                }
                List<SalesPlanStatScItemSDO> departmentScItemExtendList = result.getContent();
                departmentScItemExtendList.forEach(departmentScItem -> {
                    SalesPlanScItemExtendSDO extendSDO = new SalesPlanScItemExtendSDO();
                    BeanUtils.copyProperties(departmentScItem, extendSDO);
                    // 根据上旬计划量设置上旬回复量和任务量
                    Integer monthFirstCount = departmentScItem.getMonthFirstCount();
                    extendSDO.setMonthFirstReturnCount(monthFirstCount);
                    extendSDO.setMonthFirstTaskCount(monthFirstCount);
                    // 根据中旬计划量设置中旬回复量和任务量
                    Integer monthMiddleCount = departmentScItem.getMonthMiddleCount();
                    extendSDO.setMonthMiddleReturnCount(monthMiddleCount);
                    extendSDO.setMonthMiddleTaskCount(monthMiddleCount);
                    // 根据中旬计划量设置中旬回复量和任务量
                    Integer monthLastCount = departmentScItem.getMonthLastCount();
                    extendSDO.setMonthLastReturnCount(monthLastCount);
                    extendSDO.setMonthLastTaskCount(monthLastCount);
                    // 任务量总和就是提报量
                    extendSDO.setTaskCount(departmentScItem.getMonthCount());
                    // 计算折前任务金额
                    extendSDO.setBeforeTaskMoney(extendSDO.getTaskCount() * extendSDO.getCostInsuranceFreight());
                    // 计算折后任务金额
                    extendSDO.calculateTaskMoney(salesPlanSDO.getEstimateDiscount());
                    extendSDO.calculateTaskSatisfaction();
                    extendSDO.setId(null);
                    extendSDO.setModel(SalesPlanModelEnum.PLAN_MODEL.getModel());
                    extendSDO.setModelId(planId);
                    // 更新状态为待发布
                    extendSDO.setStatus(SalesPlanStatusEnum.TO_BE_PUBLISHED.getCode());
                    planScItemExtendSDOAllList.add(extendSDO);
                });
            }
            //回复量小于提报量，按回复量向部门回复（使用策略计算公式重新计算）
            else {
                //  公司级别的每个货品
                String scItemId = salesPlanScItemExtendSDO.getScItemId();
                // 查询该公司下  该销售组织下的该一个货品   （通过公司查不同组织的占比(策略)，就能拿到组织id，这里遍历数据，取组织id，当然一个组织对应一个占比）

                //----> TODO Start： 遍历销售组织，去计算各自的回复量
                Map<String, MonthReturn> orgMonthReturn = Maps.newHashMap();

                Map<String, BigDecimal> orgRatios = Maps.newHashMap();
                List<String> orgIds = companyScItemPlanInfo.calculateOrgIdsByScItemId(scItemId);
                for (String orgId : orgIds) {
                    Integer ratio = 0;
                    for (SalesOrgRatioDTO dto : salesOrgRatioDTOList) {
                        if (orgId.equals(dto.getSalesOrgCode())) {
                            ratio = dto.getRatio();
                        }
                    }
                    orgRatios.put(orgId, new BigDecimal(ratio));
                }

                SharePie sharePie = new SharePie(orgRatios);
                Map</* 组织ID */String, BigDecimal> firstShareRes = sharePie.share(new BigDecimal(monthFirstReturnCount), 0, RoundingMode.DOWN);
                Map</* 组织ID */String, BigDecimal> middleShareRes = sharePie.share(new BigDecimal(monthMiddleReturnCount), 0, RoundingMode.DOWN);
                Map</* 组织ID */String, BigDecimal> lastShareRes = sharePie.share(new BigDecimal(monthLastReturnCount), 0, RoundingMode.DOWN);

                for (String orgId : orgIds) {
                    MonthReturn monthReturn = new MonthReturn();
                    orgMonthReturn.put(orgId, monthReturn);

                    monthReturn.setFirst(firstShareRes.get(orgId).intValue());
                    monthReturn.setMiddle(middleShareRes.get(orgId).intValue());
                    monthReturn.setLast(lastShareRes.get(orgId).intValue());
                }
                //----> TODO End： 遍历销售组织，去计算各自的回复量

                //----> TODO Start： 遍历部门，去计算各自的回复量
                for (String orgId : orgIds) {
                    Set<String> withStrategyDepIds = salesPlanStrategyDetailSDOMap.keySet();
                    //只有有提报数据且有设置策略的部门才参与回复量分配
                    List<String> depIds = companyScItemPlanInfo
                            .get(orgId)
                            .calculateDepIdsByScItemId(scItemId, withStrategyDepIds);

                    Map<String, BigDecimal> depRatios = Maps.newHashMap();
                    for (String depId : depIds) {

                        SalesPlanStrategyDetailSDO salesPlanStrategyDetailSDO = salesPlanStrategyDetailSDOMap.get(depId);
                        SalesPlanStatScItemSDO salesPlanStatScItemSDO = companyScItemPlanInfo.get(orgId)
                                .getDepartSalesPlanStatScItemInfoMap().get(depId)
                                .get(scItemId);

                        //dept ratio = 部门提报量 * 部门提报量因子 + 部门合同量 * 部门合同量因子；
                        BigDecimal first = new BigDecimal(salesPlanStrategyDetailSDO.getFirstWeightRatio())
                                .multiply(new BigDecimal(salesPlanStatScItemSDO.getMonthCount()));
                        BigDecimal second = new BigDecimal(salesPlanStrategyDetailSDO.getSecondWeightRatio())
                                .multiply(new BigDecimal(salesPlanStatScItemSDO.getMonthContractCount()));
                        BigDecimal ratio = first.add(second);
                        depRatios.put(depId, ratio);
                    }


                    SharePie sharePie4Dept = new SharePie(depRatios);
                    Map</* depId */ String, BigDecimal> firstShareDeptRes = sharePie4Dept.share(firstShareRes.get(orgId), 0, RoundingMode.DOWN);
                    Map</* depId */ String, BigDecimal> middleShareDeptRes = sharePie4Dept.share(middleShareRes.get(orgId), 0, RoundingMode.DOWN);
                    Map</* depId */ String, BigDecimal> lastShareDeptRes = sharePie4Dept.share(lastShareRes.get(orgId), 0, RoundingMode.DOWN);


                    for (String depId : depIds) {
                        //组装待数据库变更数据
                        SalesPlanScItemExtendSDO newRecord = new SalesPlanScItemExtendSDO();
                        BeanUtils.copyProperties(companyScItemPlanInfo.get(orgId)
                                .getDepartSalesPlanStatScItemInfoMap().get(depId)
                                .get(scItemId), newRecord);

                        newRecord.setMonthFirstReturnCount(firstShareDeptRes.get(depId).intValue());
                        newRecord.setMonthFirstTaskCount(firstShareDeptRes.get(depId).intValue());
                        newRecord.setMonthMiddleReturnCount(middleShareDeptRes.get(depId).intValue());
                        newRecord.setMonthMiddleTaskCount(middleShareDeptRes.get(depId).intValue());
                        newRecord.setMonthLastReturnCount(lastShareDeptRes.get(depId).intValue());
                        newRecord.setMonthLastTaskCount(lastShareDeptRes.get(depId).intValue());

                        // 部门任务量
                        newRecord.setTaskCount(newRecord.getMonthFirstTaskCount()
                                + newRecord.getMonthMiddleTaskCount()
                                + newRecord.getMonthLastTaskCount());
                        // 计算折前任务金额
                        newRecord.setBeforeTaskMoney(newRecord.getTaskCount() * newRecord.getCostInsuranceFreight());
                        // 计算折后任务金额
                        newRecord.calculateTaskMoney(salesPlanSDO.getEstimateDiscount());
                        newRecord.calculateTaskSatisfaction();
                        newRecord.setId(null);
                        newRecord.setModel(SalesPlanModelEnum.PLAN_MODEL.getModel());
                        newRecord.setModelId(planId);
                        // 更新状态为待发布
                        newRecord.setStatus(SalesPlanStatusEnum.TO_BE_PUBLISHED.getCode());
                        planScItemExtendSDOAllList.add(newRecord);

                    }


                }
                //----> TODO End： 遍历部门，去计算各自的回复量
            }
        }


        log.info("批量新增生成部门任务量入参{}", JSON.toJSONString(planScItemExtendSDOAllList));
        //最后批量新增
        Boolean aBoolean = salesPlanScItemExtendRepository.batchCreatePlanScItemExtend(planScItemExtendSDOAllList);
        // 更新发布状态为已生成部门任务量
        SalesPlanSDO updateCheckStatusSalesPlanSDO = new SalesPlanSDO();
        updateCheckStatusSalesPlanSDO.setId(Long.valueOf(planId));
        updateCheckStatusSalesPlanSDO.setCheckStatus(SalesPlanCheckStatusEnum.DECOMPOSE_DEPARTMENT_TASK.getCode());
        salesPlanRepository.editSalesPlan(updateCheckStatusSalesPlanSDO);
        return aBoolean;
    }


    private SalesPlanStrategyDetailResponse tinglangFunc1(SalesPlanSDO salesPlanSDO){
        QuerySalesPlanStrategyListRequest querySalesPlanStrategyListRequest = new QuerySalesPlanStrategyListRequest();
        querySalesPlanStrategyListRequest.setOrgBusinessCode(salesPlanSDO.getOrgBusinessUnitCode());
        // 目前策略类型都是1(表示计划回复策略)
        querySalesPlanStrategyListRequest.setType(1);
        log.info("查询分子公司的回复策略参数{}", JSON.toJSONString(querySalesPlanStrategyListRequest));
        Result<SalesPlanStrategyDetailResponse> detailResponseResult =
                salesPlanStrategyDetailQueryService.getSalesPlanStrategyDetail(querySalesPlanStrategyListRequest);
        log.info("查询分子公司的回复策略结果{}", JSON.toJSONString(detailResponseResult));
        if (null == detailResponseResult || null == detailResponseResult.getResult()) {
            throw new FacadeException("OTS-02-004-01-15-010");
        }
        if (CollectionUtils.isEmpty(detailResponseResult.getResult().getSalesPlanStrategyDetailDepartmentList())) {
            throw new FacadeException("OTS-02-004-01-15-012");
        }

        SalesPlanStrategyDetailResponse salesPlanStrategyDetailResponse = detailResponseResult.getResult();
        // 拿到组织占比策略
        List<SalesOrgRatioDTO> salesOrgRatioDTOList = salesPlanStrategyDetailResponse.getSalesOrgRatioDTOList();
        if (CollectionUtils.isEmpty(salesOrgRatioDTOList)) {
            throw new FacadeException("OTS-02-004-01-15-011");
        }
        return salesPlanStrategyDetailResponse;
    }

    private CompanyScItemPlanInfo tinglangFunc2(String planId, List<SalesOrgRatioDTO> salesOrgRatioDTOList, SalesPlanStrategyDetailResponse salesPlanStrategyDetailResponse){
        Map<String,OrgScItemPlanInfo> map = Maps.newHashMap();
        // 遍历销售组织，去计算各自的占比
        for (SalesOrgRatioDTO salesOrgRatioDTO : salesOrgRatioDTOList) {
            OrgScItemPlanInfo orgScItemPlanInfo = new OrgScItemPlanInfo();
            // 根据策略获取组织id
            String organizationId = salesOrgRatioDTO.getSalesOrgCode();
            orgScItemPlanInfo.setOrganizationId(organizationId);
            // 查询该组织下的所有部门
            GetDownOrganizationListRequest getDownOrganizationListRequest = new GetDownOrganizationListRequest();
            getDownOrganizationListRequest.setId(organizationId);
            getDownOrganizationListRequest.setType(OrganizationTypeEnum.SALES_DEPARTMENT.getCode());
            List<OrganizationSDO> departmentSDOForOrg = null;
            Result<List<OrganizationSDO>> organizationResult = otsPlatformEnhanceService.getDownOrganizationList(getDownOrganizationListRequest);
            departmentSDOForOrg = organizationResult.getResult();
            orgScItemPlanInfo.setOrganizationSDOS(departmentSDOForOrg);

            // 查询组织下的所有计划货品
            QueryPlanScItemStatRequest queryPlanScItemStatRequest = new QueryPlanScItemStatRequest();
            queryPlanScItemStatRequest.setPlanId(Long.valueOf(planId));
            queryPlanScItemStatRequest.setBizType(SalesStatBizTypeEnum.SALES_ORGANIZATION.getBizType());
            queryPlanScItemStatRequest.setPoolType(Objects.toString(StatPoolTypeEnum.SC_ITEM.getPoolType()));
//            queryPlanScItemStatRequest.setScItemId(scItemId);
            queryPlanScItemStatRequest.setBizId(organizationId);
            queryPlanScItemStatRequest.setLimit(1000);
            queryPlanScItemStatRequest.setStart(0);
            // 下面就能查到该组织下的该货品数据 按理说只有一条
            log.info("查询分子公司下组织的汇总数据参数{}", JSON.toJSONString(queryPlanScItemStatRequest));
            PageResult<List<SalesPlanStatScItemSDO>> pageResult = salesPlanScItemStatRepository.batchQueryPlanScItemByBizId(queryPlanScItemStatRequest);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemOrganizationSDOList = pageResult.getContent();
            log.info("查询分子公司下组织的汇总数据结果{}", JSON.toJSONString(salesPlanStatScItemOrganizationSDOList));

            orgScItemPlanInfo.setOrgSalesPlanStatScItemInfoMap(salesPlanStatScItemOrganizationSDOList
                    .stream()
                    .collect(Collectors.toMap(SalesPlanStatScItemSDO::getBizId, item -> item)));


            // 查询该组织下所有部门的提报货品
            // 拿到部门策略
            List<SalesPlanStrategyDetailSDO> salesPlanStrategyDetailDepartmentList = salesPlanStrategyDetailResponse.getSalesPlanStrategyDetailDepartmentList();

            // 取出部门id列表
            List<String> departmentIdList = salesPlanStrategyDetailDepartmentList.stream().map(SalesPlanStrategyDetailSDO::getReplyTargetId).collect(Collectors.toList());
            //批量查询部门的货品提报量
            QueryPlanScItemStatRequest queryPlanScItemStatRequestForDepartment = new QueryPlanScItemStatRequest();
            queryPlanScItemStatRequestForDepartment.setPlanId(Long.valueOf(planId));
            queryPlanScItemStatRequestForDepartment.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
            queryPlanScItemStatRequestForDepartment.setPoolType(Objects.toString(StatPoolTypeEnum.SC_ITEM.getPoolType()));
//            queryPlanScItemStatRequestForDepartment.setScItemId(scItemIdByOrganization);
            queryPlanScItemStatRequestForDepartment.setBizIds(departmentIdList);
            queryPlanScItemStatRequestForDepartment.setStart(0);
            queryPlanScItemStatRequestForDepartment.setLimit(1000);
            log.info("查询分子公司下配置策略的所有部门的汇总数据参数{}", JSON.toJSONString(queryPlanScItemStatRequestForDepartment));
            PageResult<List<SalesPlanStatScItemSDO>> pageResult1 = salesPlanScItemStatRepository.batchQueryPlanScItemByBizId(queryPlanScItemStatRequestForDepartment);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemSDOList = pageResult1.getContent();
            log.info("查询分子公司下配置策略的所有部门的汇总数据结果{}", JSON.toJSONString(salesPlanStatScItemSDOList));
            // key :departmentId  value:SalesPlanStatScItemSDO
            Map</* deparmentId */ String, SalesPlanStatScItemSDO> tt = salesPlanStatScItemSDOList.stream().collect(Collectors.toMap(SalesPlanStatScItemSDO::getBizId, item -> item));
            if (MapUtils.isEmpty(map)) {
                throw new FacadeException("OTS-02-004-01-15-013");
            }

            Map</* departmentId */ String , Map</* scItemId */ String, SalesPlanStatScItemSDO>> departSalesPlanStatScItemInfoMap = Maps.newHashMap();
            for(String departmentId: departmentIdList){
                for(SalesPlanStatScItemSDO salesPlanStatScItemSDO: salesPlanStatScItemSDOList) {
                    Map</* scItemId */ String, SalesPlanStatScItemSDO> tmp = Maps.newHashMap();
                    tmp.put(salesPlanStatScItemSDO.getScItemId(), salesPlanStatScItemSDO);
                    departSalesPlanStatScItemInfoMap.put(departmentId, tmp);
                }
            }
            orgScItemPlanInfo.setDepartSalesPlanStatScItemInfoMap(departSalesPlanStatScItemInfoMap);
            map.put(organizationId, orgScItemPlanInfo);
        }

        CompanyScItemPlanInfo companyScItemPlanInfo = new CompanyScItemPlanInfo();
        companyScItemPlanInfo.setCompanyScItemInfo(map);
        return companyScItemPlanInfo;

    }

    /**
     * 计算部门理论回复量
     *
     * @param monthCount         提报量
     * @param monthContractCount 合同量
     * @param firstWeightRatio   提报因子
     * @param secondWeightRatio  合同因子
     * @return
     */
    private Integer getTheoryReturnCount(Integer monthCount, Integer monthContractCount, Integer firstWeightRatio, Integer secondWeightRatio) {
        BigDecimal firstWeightRatioNew = new BigDecimal(firstWeightRatio).multiply(new BigDecimal(0.0001)).setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal secondWeightRatioNew = new BigDecimal(secondWeightRatio).multiply(new BigDecimal(0.0001)).setScale(2, BigDecimal.ROUND_HALF_UP);
        // 部门理论回复量   (部门提报量*提报因子+合同量*合同因子)
        Integer theoryReturnCount = (new BigDecimal(monthCount).multiply(firstWeightRatioNew).setScale(0, BigDecimal.ROUND_HALF_UP))
                .add(new BigDecimal(monthContractCount).multiply(secondWeightRatioNew).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue();
        return theoryReturnCount;
    }

    private void checkParam(DispatchPlanScItemRequest dispatchPlanScItemRequest) {
        if (StringUtils.isBlank(dispatchPlanScItemRequest.getPlanId())) {
            throw new ActivityException("OTS-02-004-01-15-001");
        }
//        if (null == dispatchPlanScItemForDepartmentRequest.getBizType()) {
//            throw new ActivityException("OTS-02-004-01-15-002");
//        }
//        if (null == dispatchPlanScItemRequest.getBizId()) {
//            throw new ActivityException("OTS-02-004-01-15-003");
//        }

    }

    /**
     * 合同量根据三旬均衡拆分上中下旬（和计划量的拆分一样）
     * salesPlanSDO   计划信息
     * monthContractCount 月份合同量
     * return  上中下旬合同量Map<String, Integer>
     */
    private Map<String, Integer> getBalanceContract(SalesPlanSDO salesPlanSDO, Integer monthContractCount) {
        Map<String, Integer> ContractCountMap = new HashMap();
        BigDecimal sum = salesPlanSDO.getMonthFirstProprtion().add(salesPlanSDO.getMonthMiddleProprtion()).add(salesPlanSDO.getMonthLastProprtion());
        if (new BigDecimal(100).compareTo(sum) == 0) {
            //月度计划有配置三旬比例均衡
            //上旬合同量
            BigDecimal monthFirstProprtion = salesPlanSDO.getMonthFirstProprtion();
            BigDecimal firstCount = monthFirstProprtion.multiply(new BigDecimal(Optional.ofNullable(monthContractCount).orElse(0)));
            Integer monthFirstContractCount = firstCount.divide(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_DOWN).intValue();
            ContractCountMap.put("monthFirstContractCount", monthFirstContractCount);

            //下旬合同量
            BigDecimal monthLastProprtion = salesPlanSDO.getMonthLastProprtion();
            BigDecimal LastCount = monthLastProprtion.multiply(new BigDecimal(Optional.ofNullable(monthContractCount).orElse(0)));
            Integer monthLastContractCount = LastCount.divide(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_DOWN).intValue();
            ContractCountMap.put("monthLastContractCount", monthLastContractCount);

            //中旬合同量
            Integer monthMiddleContractCount = monthContractCount - (monthFirstContractCount + monthLastContractCount);
            ContractCountMap.put("monthMiddleContractCount", monthMiddleContractCount);
        }
        return ContractCountMap;
    }

    /**
     * 校验计划
     *
     * @param planId
     * @return
     */
    private SalesPlanSDO checkPlan(String planId) {
        QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
        querySalesPlanRequest.setId(planId);
        SalesPlanSDO salesPlanSDO = salesPlanRepository.load(querySalesPlanRequest);
        if (Objects.isNull(salesPlanSDO)) {
            throw new FacadeException("OTS-02-002-00-16-001");
        }
        Integer status = salesPlanSDO.getStatus();
        if (!SalesPlanStatusEnum.TO_BE_PUBLISHED.getCode().equals(status)) {
            throw new FacadeException("OTS-02-004-01-15-004");
        }
        return salesPlanSDO;
    }


}
